package com.ruoyi.web.service.impl;

import com.gitee.deeround.jdbchelper.DbAction;
import com.gitee.deeround.jdbchelper.resultSetExtractors.CustomApply;
import com.ruoyi.core.entity.BaseMap;
import com.ruoyi.web.context.RequestContextHolder;
import com.ruoyi.web.domain.SysModColumn;
import com.ruoyi.web.entity.system.MenuVo;
import com.ruoyi.web.mapper.SysModColumnMapper;
import com.ruoyi.web.mapper.SysModMapper;
import com.ruoyi.web.service.SysSystemService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SysSystemServiceImpl implements SysSystemService {

    @Autowired
    private DbAction dbAction;

    @Autowired
    private SysModMapper sysModMapper;

    @Autowired
    private SysModColumnMapper sysModColumnMapper;

    /**
     * 根据用户角色、角色菜单获取当前用户有权限的菜单，管理员不判断权限，直接查询全部
     *
     * @return
     */
    @Override
    public List<MenuVo> getUserMenu() {
        String userId = RequestContextHolder.currentUserId();
        String sql = "select c.* from sys_user_role a,sys_role_menu b,sys_menu c where a.user_id =? and a.role_id =b.role_id and b.menu_id=c.menu_id and c.status='1' ";
        List<BaseMap> list = null;

        if ("1".equals(RequestContextHolder.currentUserType())) {
            sql = "select * from sys_menu where status='1' order by order_num asc";
            list = dbAction.queryForListObject(sql, new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else {
            list = dbAction.queryForListObject(sql, new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            }, userId);
        }


        List<MenuVo> menuVos = new ArrayList<>();
        for (BaseMap map : list) {
            MenuVo menuVo = new MenuVo();
            menuVo.setId(map.getString("menu_id"));
            menuVo.setPid(map.getString("parent_id"));
            menuVo.setPath(map.getString("path"));
            menuVo.setName(map.getString("perms"));
            menuVo.setComponent(map.getString("component"));
            MenuVo.MenuMeta meta = new MenuVo.MenuMeta();
            meta.setIcon(map.getString("icon"));
            meta.setTitle(map.getString("menu_name"));
            meta.setIsLink(map.getBoolean("is_link"));
            meta.setIsHide(map.getBoolean("is_hide"));
            meta.setIsFull(map.getBoolean("is_full"));
            meta.setIsAffix(map.getBoolean("is_affix"));
            meta.setIsKeepAlive(map.getBoolean("is_keep_alive"));
            menuVo.setMeta(meta);
            menuVo.setChildren(new ArrayList<>());
            menuVos.add(menuVo);
        }

        // 1. 找出所有的根节点（parentId为null或某个特定值，如0）
        List<MenuVo> rootNodes = menuVos.stream()
                .filter(item -> item.getPid() == null || "0".equals(item.getPid()))
                .collect(Collectors.toList());

        // 2. 构建子节点并附加到对应的父节点上
        for (MenuVo node : rootNodes) {
            buildChildren(node, menuVos);
        }

        return rootNodes;
    }

    private void buildChildren(MenuVo parent, List<MenuVo> items) {
        for (MenuVo item : items) {
            if (item.getPid().equals(parent.getId())) {
                parent.getChildren().add(item);
                buildChildren(item, items);
            }
        }
    }

    @Override
    public List<BaseMap> getDictData(String dictType) {
        List<BaseMap> list = dbAction.queryForListObject("select dict_code as id,dict_name as name,parent_id as pid from sys_dict_data where dict_type_id=(select dict_type_id from sys_dict_type where dict_type_code=?)", new CustomApply<BaseMap>() {
            @Override
            public BaseMap apply(Map<String, Object> map) {
                return new BaseMap(map);
            }
        }, dictType);
        return list;
    }

    /**
     * 根据用户角色、角色模型获取当前用户有权限的模型，管理员不判断权限，直接查询全部
     *
     * @return
     */
    @Override
    public List<BaseMap> getUserMod() {

        List<BaseMap> list = dbAction.queryForListObject("select * from sys_mod_group where status='1' order by order_num asc", new CustomApply<BaseMap>() {
            @Override
            public BaseMap apply(Map<String, Object> map) {
                return new BaseMap(map);
            }
        });

        String userId = RequestContextHolder.currentUserId();
        String sql = "select c.* from sys_user_role a,sys_role_mod b,sys_mod c where a.user_id =? and a.role_id =b.role_id and b.mod_id=c.mod_id";
        List<BaseMap> list1 = null;

        if ("1".equals(RequestContextHolder.currentUserType())) {
            sql = "select * from sys_mod where status='1' order by order_num asc";
            list1 = dbAction.queryForListObject(sql, new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else {
            list1 = dbAction.queryForListObject(sql, new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            }, userId);
        }

        List<BaseMap> finalList = list1;
        list.forEach(x -> {
            String groupId = x.getString("group_id");
            List<BaseMap> list3 = finalList.stream().filter(y -> groupId.equals(y.getString("group_id"))).collect(Collectors.toList());
            x.put("mods", list3);
        });


        return list;
    }

    @Override
    public List<BaseMap> getColumnDataSource(String columnId) {

        SysModColumn column = sysModColumnMapper.selectById(columnId);
        List<BaseMap> list = new ArrayList<>();

        if ("dict".equals(column.getDataSourceType())) {
            list = dbAction.queryForListObject("select dict_code as id,dict_name as name,parent_id as pid from sys_dict_data where dict_type_id=(select dict_type_id from sys_dict_type where dict_type_code=?)", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            }, column.getDataSource());
        } else if ("custom".equals(column.getDataSourceType())) {

            list = getCustomDataSource(column.getDataSource());

        }

        return list;
    }

    @Override
    public List<BaseMap> getCustomDataSource(String dataSourceCode) {

        List<BaseMap> list = new ArrayList<>();

        if ("sys_dict_type".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select dict_type_id as id,dict_type_name as name from sys_dict_type", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else if ("sys_dict_data".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select dict_code as id,dict_name as name,parent_id as pid from sys_dict_data", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else if ("sys_menu".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select menu_id as id,menu_name as name,parent_id as pid from sys_menu where status='1' order by order_num asc", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else if ("sys_dept".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select dept_id as id,dept_name as name,parent_id as pid from sys_dept where status='1' order by order_num asc", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else if ("sys_role".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select role_id as id,role_name as name from sys_role where status='1'", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else if ("sys_mod".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select mod_id as id,mod_name as name from sys_mod where status='1' order by id asc", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else if ("mod_group".equalsIgnoreCase(dataSourceCode)) {
            list = dbAction.queryForListObject("select group_id as id,group_name as name from sys_mod_group where status='1' order by order_num asc", new CustomApply<BaseMap>() {
                @Override
                public BaseMap apply(Map<String, Object> map) {
                    return new BaseMap(map);
                }
            });
        } else {
            // 说明是动态的内置数据源
            String s = dbAction.queryForString("select content from sys_mod_datasource where id=?", dataSourceCode);
            if (!StringUtils.isEmpty(s)) {
                list = dbAction.queryForListObject(s, new CustomApply<BaseMap>() {
                    @Override
                    public BaseMap apply(Map<String, Object> map) {
                        return new BaseMap(map);
                    }
                });
            }
        }


        return list;
    }
}
